﻿using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reactive;
using System.Text;
using System.Threading.Tasks;

namespace chen_bot_ui.ViewModels
{
    public class ProcessViewModel : ViewModelBase
    {
        public ReactiveCommand<Unit, Unit> StartCommand { get; }
        public ReactiveCommand<Unit, Unit> StopCommand { get; }
        public FileSelectViewModel FileSelect { get; } = new();
        private Process? _process;
        private string _commandLog, _runLog, _host, _port, _token;

        public string Host
        {
            get => _host;
            set => this.RaiseAndSetIfChanged(ref _host, value);
        }

        public string Port
        {
            get => _port;
            set => this.RaiseAndSetIfChanged(ref _port, value);
        }

        public string Token
        {
            get => _token;
            set => this.RaiseAndSetIfChanged(ref _token, value);
        }

        public ProcessViewModel()
        {
            _runLog = _host = _port = _token = string.Empty;
            _commandLog = " ";
            StartCommand = ReactiveCommand.Create(Start, FileSelect.IsFileSelected);
            StopCommand = ReactiveCommand.Create(Stop);
            
            // this.WhenAnyValue<ProcessViewModel, string, string>(x => x.FileSelect.FilePath, filePath => filePath)
            //     .Subscribe(filePath =>
            //     {
            //         try
            //         {
            //             Configuration config = ConfigurationManager.OpenExeConfiguration(filePath);
            //             var settings = config.AppSettings.Settings;
            //             if (settings["Host"] is not null)
            //                 Host = settings["Host"].Value;
            //             if (settings["Port"] is not null)
            //                 Port = settings["Port"].Value;
            //             if (settings["AccessToken"] is not null)
            //                 Token = settings["AccessToken"].Value;
            //         }
            //         catch (Exception)
            //         {
            //             // ignored
            //         }
            //     });
        }

        private void Start()
        {
            if (_process != null)
            {
                CommandLog = "已有程序启动，请先停止";
                return;
            }

            try
            {


                Configuration config = ConfigurationManager.OpenExeConfiguration(FileSelect.FilePath);
                var settings = config.AppSettings.Settings;

                void SetConfig(string key, string value)
                {
                    if (settings[key] is null)
                        settings.Add(key, value);
                    else settings[key].Value = value;
                }

                if (Host != string.Empty) SetConfig("Host", Host);
                if (Port != string.Empty) SetConfig("Port", Port);
                if (Token != string.Empty) SetConfig("AccessToken", Token);
                config.Save(ConfigurationSaveMode.Modified);

                _process = new Process()
                {
                    StartInfo = new ProcessStartInfo()
                    {
                        FileName = FileSelect.FilePath,
                        Arguments = "",
                        WorkingDirectory = Path.GetDirectoryName(FileSelect.FilePath),
                        UseShellExecute = false,
                        RedirectStandardOutput = true,
                        RedirectStandardError = true,
                        CreateNoWindow = true,
                    },
                };

                RunLog = string.Empty;

                // 应该是为重定向的流增加有输出时的事件
                _process.OutputDataReceived += (_, args) => { RunLog += $"{args.Data}\n"; };
                _process.ErrorDataReceived += (_, args) => { RunLog += $"{args.Data}\n"; };

                _process.Start();

                // 开始读取重定向的流
                _process.BeginOutputReadLine();
                _process.BeginErrorReadLine();

                CommandLog = "启动成功";
            }
            catch (Exception ex)
            {
                CommandLog = $"启动时发生错误，错误信息为：{ex.Message}";
                _process = null;
            }
        }

        private void Stop()
        {
            if (_process == null)
            {
                CommandLog = "没有程序在运行";
                return;
            }
            try
            {
                _process.Kill();
                _process = null;
                CommandLog = "停止成功";
            }
            catch (Exception ex)
            {
                CommandLog = $"停止时发生错误，错误信息为：{ex.Message}";
            }

        }
        public string RunLog
        {
            get => _runLog;
            private set => this.RaiseAndSetIfChanged(ref _runLog, value);
        }

        public string CommandLog
        {
            get => _commandLog;
            private set => this.RaiseAndSetIfChanged(ref _commandLog, value);
        }
    }
}
